import os
import pandas as pd


def is_none_null(vol):
    vol_new = str(vol).strip().lower()
    none_str_set = {"", "none", "nan", "&", "-", "null", "无", "nat"}
    if vol_new in none_str_set:
        return True
    return False


def get_df_data(df_data, float_columns_list=[]):
    # 将每列的数据类型先转换为 object 类型，然后再转换为字符串类型
    # 将 NaN 值替换为字符串 "NaN"
    df_data = df_data.fillna('')
    # 遍历除交易金额和交易余额两列以外的所有列，并将数据类型改为字符串，并去除两端空格和制表符
    for column in df_data.columns:
        if column not in float_columns_list:
            df_data.loc[:, column] = df_data[column].astype(str).str.strip()
        else:
            # 使用apply函数和lambda表达式进行转换，遇到无法转换的情况则返回0
            df_data.loc[:, column] = df_data[column].apply(lambda x: pd.to_numeric(str(x).strip(), errors='coerce')).fillna(
                0)
    return df_data


def delete_time_null_column(df_data):
    df_data = df_data[df_data['交易时间'].apply(lambda x: not is_none_null(x))]
    return df_data


def get_sheet_list(file_path):
    """
    获取 Excel 文件中的工作表列表

    参数:
        file_path (str): Excel 文件的路径

    返回:
        list: 工作表名称列表
    """
    # 使用 pandas 读取 Excel 文件
    xls = pd.ExcelFile(file_path)

    # 获取所有工作表名称
    sheet_names = xls.sheet_names

    return sheet_names


def read_csv_with_encoding(file_path, encodings=['utf-8', 'gbk', 'gb2312', 'gb18030']):
    """
    读取CSV文件，并根据给定的编码列表尝试不同的编码方式。
    如果无法成功读取，则返回None。
    """
    for encoding in encodings:
        try:
            with open(file_path, 'rb') as f:
                # 使用检测到的编码方式读取文件
                # print(f"正在尝试使用编码方式{encoding}读取文件{file_path}")
                df = pd.read_csv(file_path, encoding=encoding, dtype=str, on_bad_lines='skip')
                return df
        except (UnicodeDecodeError, ValueError):
            # 如果使用当前编码方式读取文件时出现解码错误或其他错误，则尝试下一个编码方式
            continue
    # 如果所有编码方式都尝试失败，则返回None
    return None


def get_df_data_from_csv(csv_file_path, float_columns_list=[]):
    # print('Reading file: {}'.format(file_path))
    df = read_csv_with_encoding(csv_file_path)
    if df is None:
        return None
    # 将每列的数据类型先转换为 object 类型，然后再转换为字符串类型
    # 将 NaN 值替换为字符串 "NaN"
    df = df.fillna('')
    # 去除标题中列名两边的空格和制表符
    df.rename(columns=lambda x: x.strip(), inplace=True)
    # 遍历除交易金额和交易余额两列以外的所有列，并将数据类型改为字符串，并去除两端空格和制表符
    for column in df.columns:
        if column not in float_columns_list:
            df[column] = df[column].astype(str).str.strip()
        else:
            # 使用apply函数和lambda表达式进行转换，遇到无法转换的情况则返回0
            df[column] = df[column].apply(lambda x: pd.to_numeric(str(x).strip(), errors='coerce')).fillna(0)
    return df


def fill_sort_columns(df_data, all_columns_list):
    for column in all_columns_list:
        if column in df_data.columns:
            continue
        else:
            df_data[column] = ""
    df_data = df_data[all_columns_list]
    return df_data


def df_data_save_file(df_data, save_file_name):
    # 获取file_name的目录部分
    folder_path = os.path.dirname(save_file_name)
    # 如果目录不存在，则创建目录
    if not os.path.exists(folder_path):
        try:
            os.makedirs(folder_path)
        except:
            pass
    # 检测文件结尾是否为csv，如果不是则添加.csv
    if save_file_name.endswith('.csv'):
        df_data.to_csv(save_file_name, index=False, quoting=1)
    elif save_file_name.endswith('.xlsx'):
        # 使用with语句创建ExcelWriter对象
        with pd.ExcelWriter(save_file_name, engine='xlsxwriter') as writer:
            # 设置每个sheet页的行数
            num_rows_per_sheet = 500000
            # 将数据写入Excel文件的多个sheet页
            for i in range(0, len(df_data), num_rows_per_sheet):
                df_part = df_data.iloc[i:i + num_rows_per_sheet]
                sheet_name = 'Sheet{}'.format(i // num_rows_per_sheet + 1)
                df_part.to_excel(writer, sheet_name=sheet_name, index=False)
    else:
        df_data.to_csv(save_file_name, index=False, quoting=1)



